package com.suray.basic.wcs.utils;

import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

/**
 * 公共方法类
 */
public class WcsFuncUtil {

    public static final String COLON_CONNECTOR = ":";

    public static final String HTTP_CONNECTOR = "http://";

    public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss:SSS");

    /**
     * 获取本机Ip地址
     *
     * @return
     */
    public static List<String> getIpAddress() throws SocketException {
        List<String> list = new LinkedList<>();
        Enumeration enumeration = NetworkInterface.getNetworkInterfaces();
        while (enumeration.hasMoreElements()) {
            NetworkInterface network = (NetworkInterface) enumeration.nextElement();
            Enumeration addresses = network.getInetAddresses();
            while (addresses.hasMoreElements()) {
                InetAddress address = (InetAddress) addresses.nextElement();
                if (address != null && (address instanceof Inet4Address || address instanceof Inet6Address)) {
                    list.add(address.getHostAddress());
                }
            }
        }
        return list;
    }

    public static String arrayToHexString(int[] a) {
        if (a == null)
            return "null";
        int iMax = a.length - 1;
        if (iMax == -1)
            return "[]";

        StringBuilder b = new StringBuilder();
        b.append('[');
        for (int i = 0; ; i++) {
            b.append("0x" + Integer.toHexString(a[i]));
            if (i == iMax)
                return b.append(']').toString();
            b.append(", ");
        }
    }

    /**
     * 睡眠
     *
     * @param time:时间（ms）
     */
    public static void delay(long time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static String arrayToHexString(byte[] a) {
        if (a == null)
            return "null";
        int iMax = a.length - 1;
        if (iMax == -1)
            return "[]";

        StringBuilder b = new StringBuilder();
        b.append('[');
        for (int i = 0; ; i++) {
            b.append(Integer.toString(a[i], 16));
            if (i == iMax)
                return b.append(']').toString();
            b.append(", ");
        }
    }

    public static String arrayToHexString(short[] a) {
        if (a == null)
            return "null";
        int iMax = a.length - 1;
        if (iMax == -1)
            return "[]";

        StringBuilder b = new StringBuilder();
        b.append('[');
        for (int i = 0; ; i++) {
            b.append(Integer.toHexString(a[i]));
            if (i == iMax)
                return b.append(']').toString();
            b.append(", ");
        }
    }

    public static String arrayToHexString(char[] a) {
        if (a == null)
            return "null";
        int iMax = a.length - 1;
        if (iMax == -1)
            return "[]";

        StringBuilder b = new StringBuilder();
        b.append('[');
        for (int i = 0; ; i++) {
            b.append(Integer.toHexString(a[i]));
            if (i == iMax)
                return b.append(']').toString();
            b.append(", ");
        }
    }

    /**
     * 拼接数组
     *
     * @param arrayPre
     * @param arrayAft
     * @return
     */
    public static byte[] combineArray(byte[] arrayPre, byte[] arrayAft) {
        byte[] array = new byte[arrayPre.length + arrayAft.length];
        System.arraycopy(arrayPre, 0, array, 0, arrayPre.length);
        System.arraycopy(arrayAft, 0, array, arrayPre.length, arrayAft.length);

        return array;
    }

    /**
     * list打印
     *
     * @param objs
     * @return
     */
    public static String listToString(Collection<?> objs) {
        if (objs == null) {
            return "";
        }

        StringBuffer sb = new StringBuffer();

        objs.forEach(obj -> {
            sb.append(obj.toString());
            sb.append(",");
        });

        return sb.toString();
    }

    /**
     * 打印抛错具体信息
     *
     * @param e
     * @param clazz
     */
    public static void exceptionLog(Throwable e, Class<?> clazz) {
        LoggerUtil.error("{}", e.getMessage(), e, clazz);
    }

    /**
     * 打印抛错具体信息
     *
     * @param e
     * @param clazz
     */
    public static void exceptionLog(ModuleType moduleType, LoggerType type, Integer param, Object res, Throwable e,
                                    Class<?> clazz) {
        LoggerUtil.error(moduleType, type, param, res, "{}", e.getMessage(), e, clazz);
    }

    /**
     * 返回list最后一个对象
     *
     * @param list
     * @param <T>
     * @return
     */
    public static <T> T getLastObj(List<T> list) {
        return list.get(list.size() - 1);
    }

    /**
     * 高低字节交换
     *
     * @param value
     * @return
     */
    public static int changeWordFormat(int value) {
        return ((value & 0xFF) << 8) + ((value & 0xFF00) >> 8);
    }

    /**
     * 4字节数据字节顺序反转
     *
     * @param value
     * @return
     */
    public static int changeDWordFormat(int value) {
        return ((value & 0xFF) << 24) + ((value & 0xFF00) << 8) + ((value & 0xFF0000) >> 8) + (((value & 0xFF000000) >> 24) & 0xFF);
    }

    /**
     * 转成有符号字节
     *
     * @param value
     * @return
     */
    public static int calcRealByte(int value) {
        return Integer.valueOf(value).byteValue();
    }

    /**
     * 转成有符号双字节
     *
     * @param value
     * @return
     */
    public static int calcRealWord(int value) {
        return Integer.valueOf(value).shortValue();
    }

    /**
     * 转成有符号四字节
     *
     * @param value
     * @return
     */
    public static int calcRealDWord(int value) {
        return Integer.valueOf(value).intValue();
    }

    public static void main(String[] args) {
        WcsFuncUtil.changeDWordFormat(0x11700001);
    }

    /**
     * 两个字节组合成一个Word
     *
     * @param low
     * @param high
     * @return
     */
    public static int combineToWord(byte low, byte high) {
        return (((int) high << 8) & 0xFFFF) + (low & 0xFF);
    }

    /**
     * 4个字节组合成DWord
     *
     * @param low
     * @param midLow
     * @param midHigh
     * @param high
     * @return
     */
    public static int combineToDWord(byte low, byte midLow, byte midHigh, byte high) {
        return (((int) high << 24) & 0xFFFFFFFF) + (((int) midHigh << 16) & 0xFFFFFF) + (((int) midLow << 8) & 0xFFFF) + (low & 0xFF);
    }

    /**
     * 2个Word组合成DWord
     *
     * @param low
     * @param high
     * @return
     */
    public static int combineToDWord(int low, int high) {
        return ((high << 16) & 0xFFFFFFFF) + (low & 0xFFFF);
    }

    /**
     * 字节数组转成16进制字符串
     *
     * @param data
     * @return
     */
    public static String changeToHexString(byte[] data) {
        StringBuffer sb = new StringBuffer();

        for (byte b : data) {
            sb.append(byteToHexString(b).toUpperCase());
            sb.append(" ");
        }

        return sb.toString();
    }

    /**
     * 单字节转换成16进制字符串
     *
     * @param b
     * @return
     */
    private static String byteToHexString(byte b) {
        String str = Integer.toHexString(b);

        if (str.length() > 2) {
            return str.substring(str.length() - 2);
        } else if (str.length() == 1) {
            return "0" + str;
        } else if (str.length() == 0) {
            return "00";
        }

        return str;
    }

    /**
     * 父类的数据拷贝到子类
     *
     * @param father
     * @param child
     * @throws Exception
     */
    public static void copy(Object father, Object child) throws Exception {
        fatherToChild(father, child);
    }

    /*
     * 将父类所有的属性COPY到子类中。
     * 类定义中child一定要extends father；
     * 而且child和father一定为严格javabean写法，属性为deleteDate，方法为getDeleteDate
     */
    private static void fatherToChild(Object father, Object child) throws Exception {
        if (!(child.getClass().getSuperclass() == father.getClass())) {
            throw new Exception("child不是father的子类");
        }
        Class fatherClass = father.getClass();
        Field ff[] = fatherClass.getDeclaredFields();
        for (int i = 0; i < ff.length; i++) {
            Field f = ff[i];//取出每一个属性，如deleteDate
            Class type = f.getType();
            Method m = fatherClass.getMethod("get" + upperHeadChar(f.getName()));//方法getDeleteDate
            Object obj = m.invoke(father);//取出属性值
            f.set(child, obj);
        }
    }

    /**
     * 首字母大写，in:deleteDate，out:DeleteDate
     */
    private static String upperHeadChar(String in) {
        String head = in.substring(0, 1);
        String out = head.toUpperCase() + in.substring(1, in.length());
        return out;
    }

    /**
     * 创建文件夹
     *
     * @param path
     * @throws IOException
     */
    public static void createPaper(String path) throws IOException {
        File file = new File(path);
        File fileParent = file.getParentFile();
        if (!fileParent.exists()) {
            fileParent.mkdirs();
        }
        file.createNewFile();
    }

    public static boolean isNullList(List<?> pathNodes) {
        if (pathNodes == null || pathNodes.size() == 0) {
            return true;
        }

        return false;
    }

    //获取写入文件路径
    public static String getPaperFilePath(ModuleType moduleType, String wareHouse) {
        String rgvTypeName = null;
        if (moduleType == ModuleType.RGV_60) {
            rgvTypeName = "Rgv_60";
        } else if (moduleType == ModuleType.RGV_ROLLER) {
            rgvTypeName = "Rgv_Roller";
        } else if (moduleType == ModuleType.RGV_SON_MOTHER) {
            rgvTypeName = "Rgv_Son_Mother";
        } else if (moduleType == ModuleType.RGV_SON_MOTHER) {
            rgvTypeName = "Rgv_Fork";
        }
        if (rgvTypeName == null) {
            throw new RuntimeException("获取文件路径错误");
        }
        String paperFile = System.getProperty("user.dir") + File.separator + "wcs_map" + File.separator + wareHouse
                + File.separator + rgvTypeName;
        return paperFile;
    }

    /**
     * 读取文件
     *
     * @param path 文件路径
     * @throws IOException
     */
    public static String readFile(String path) throws IOException {
        File file = new File(path);
        FileInputStream fileInputStream = null;
        StringBuffer sb = new StringBuffer();
        try {
            fileInputStream = new FileInputStream(file);
            int ch = 0;
            while ((ch = fileInputStream.read()) != -1) {
                sb.append((char) ch);
            }
        } catch (FileNotFoundException e) {
            throw e;
        } catch (IOException e) {
            throw e;
        } finally {
            if (fileInputStream != null) {
                fileInputStream.close();
            }
        }
        return sb.toString();
    }

    /**
     * 向指定路径写文件内容
     *
     * @param filePath 文件路径
     * @param content  文件内容
     */
    public static void writeFile(String filePath, String content) throws IOException {
        String folderPath = filePath.substring(0, filePath.lastIndexOf("\\"));
        File file = new File(folderPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(filePath);
            try {
                fileOutputStream.write(content.getBytes());
            } catch (IOException e) {
                throw e;
            }
        } catch (FileNotFoundException e) {
            throw e;
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    throw e;
                }
            }
        }
    }

    /**
     * map打印
     *
     * @param objs
     * @return
     */
    public static String mapToString(Map<?, ?> objs) {
        StringBuffer sb = new StringBuffer();

        Iterator itKey = objs.keySet().iterator();
        Iterator itValues = objs.values().iterator();

        while (itKey.hasNext()) {
            Object objKey = itKey.next();
            Object objValue = itValues.next();
            sb.append(objKey.toString());
            sb.append(",");
            sb.append(objValue.toString());
            sb.append(",");
        }

        return sb.toString();
    }

    /**
     * 获取http url
     *
     * @param ip
     * @param port
     * @param path
     * @return
     */
    public static String getHttpUrl(String ip, String port, String path) {
        return new StringBuilder().append(HTTP_CONNECTOR).append(ip).append(COLON_CONNECTOR).append(port).append(path).toString();
    }

    /**
     * 获取高16位数据
     *
     * @param dWord
     * @return
     */
    public static int getHighWord(int dWord) {
        return (dWord >> 16) & 0xFFFF;
    }

    /**
     * 获取低16位数据
     *
     * @param dWord
     * @return
     */
    public static int getLowWord(int dWord) {
        return dWord & 0xFFFF;
    }

    public static byte[] changeData(String jason) throws UnsupportedEncodingException {
        return jason.getBytes("UTF-8");
    }

    public static String changeData(byte[] data) throws UnsupportedEncodingException {
        return new String(data, "UTF-8");
    }

    /**
     * 字符串是否为数字
     * @param str
     * @return
     */
    public static boolean isInteger(String str) {
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }
}
